package com.mzj.saas.filter;

import com.mzj.saas.commons.vo.redis.TokenRedisVo;
import com.mzj.saas.mservice.enterprise.entity.EnterpriseOperation;
import com.mzj.saas.mservice.enterprise.repository.EnterpriseOperationRepository;
import com.mzj.saas.mservice.sys.entity.Permission;
import com.mzj.saas.mservice.sys.repository.PermissionRepository;
import com.mzj.saas.redis.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

@Component
public class AsyncHandleLogFactory {
    private static Logger LOG = LoggerFactory.getLogger(AsyncHandleLogFactory.class);
    @Autowired
    private RedisService redisService;
    @Autowired
    private PermissionRepository permissionRepository;
    @Autowired
    private EnterpriseOperationRepository enterpriseOperationRepository;

    /**
     * 操作日志记录
     *
     * @param accessToken
     * @param path
     * @param requestParam
     * @param method
     * @author shun
     * @date 2021年6月8日
     */
    @Async
    public void recordOper(final String accessToken, final String path, final String requestParam, final String method) {
        List<Permission> permissionList = redisService.getAllPerissionRedis();

        if (permissionList == null || permissionList.isEmpty()) {
            permissionList = permissionRepository.findAll();
            // 临时注释
            redisService.putAllPerissionRedis(permissionList);
        }
        if (accessToken == null) {
            return;
        }

        // 获取当前的用户
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        if (tokenRedisVo == null) {
            return;
        }
        // ========数据库日志=========
        EnterpriseOperation operLog = new EnterpriseOperation();
        // 用户id
        operLog.setUserId(tokenRedisVo.getId());
        // 机构id
        operLog.setOrgId(tokenRedisVo.getEnterpriseId());
        // 用户类型：0普通用户 1管理员
        if (tokenRedisVo.getMasterStatus() != null && tokenRedisVo.getMasterStatus() == 1) {
            operLog.setType(1);
        } else {
            operLog.setType(0);
        }

        // 操作功能
        for (Permission vo : permissionList) {
            if (!method.equalsIgnoreCase(vo.getMethod())) {
                continue;
            }

            if (StringUtils.isEmpty(vo.getUrl())) {
                continue;
            }

            String urlPattern = replace(vo.getUrl());
            boolean isMatch = Pattern.matches(urlPattern, path);
            if (isMatch) {
                // 操作功能:应用名称
                operLog.setOperationFunction(vo.getName());
                break;
            }
        }

        // 操作类型
        operLog.setOperationType(method);
        // 操作功能
        String operationFunction = null;
        if (method.equalsIgnoreCase("GET")) {
            operationFunction = "查询";
        } else if (method.equalsIgnoreCase("POST")) {
            operationFunction = "新增";
        } else if (method.equalsIgnoreCase("PUT")) {
            operationFunction = "修改";
        } else if (method.equalsIgnoreCase("DELETE")) {
            operationFunction = "删除";
        }
        operLog.setOperationFunction(operationFunction);
        // 明细参数
        operLog.setDetail(path);
        // 时间
        operLog.setOperationTime(new Date());

        enterpriseOperationRepository.save(operLog);
    }

    private static String replace(String url) {
        if (StringUtils.isEmpty(url)) {
            return url;
        }

        int start = url.indexOf("{", 0);
        if (start <= 0) {
            return url;
        }

        int end = url.indexOf("}", start);
        try {
            String repStr = url.substring(start, end + 1);
            url = url.replace(repStr, "\\w+");
            return replace(url);
        } catch (Exception e) {
            LOG.error("URL format invalid {}", url);
            LOG.error(e.getMessage(), e);
        }

        return url;
    }
}
